package com.shopx.auth.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.shopx.auth.DTO.LevelOrgDTO;
import com.shopx.auth.bean.SysOrg;
import com.shopx.auth.dao.db1.SysOrgDao;
import com.shopx.auth.dao.db1.SysUserDao;
import com.shopx.auth.model.*;
import com.shopx.auth.model.SysOrgModel;
import com.shopx.auth.service.ISysOrgService;
import com.shopx.auth.service.ISysUserService;
import com.shopx.base.constants.ResultCodeEnum;
import com.shopx.base.exception.OriginException;
import com.shopx.base.exception.ShopxException;
import com.shopx.base.service.ISysSeqService;
import com.shopx.cmm.DTO.PageDTO;
import com.shopx.config.service.ISysDictService;
import com.shopx.core.common.CommonConstant;
import com.shopx.core.utils.ClazzUtil;
import com.shopx.core.utils.StringUtil;
import com.shopx.dal.redis.RedisCacheService;
import com.shopx.sys.service.ISysCompanyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * SysOrg
 *
 * @author lituo 2021-09-04
 */
@Service
@Slf4j
public class SysOrgServiceImpl extends BaseAuthService implements ISysOrgService {

  @Autowired
  private SysOrgDao sysOrgDao;

  @Autowired
  private SysUserDao sysUserDao;

  @Autowired
  private ISysUserService sysUserService;

  @Autowired
  private ISysSeqService sysSeqService;

  @Resource
  private RedisCacheService redisCacheService;

  /**
   * 从父级组织机构获取下面所有的组织机构
   * @return
   * @throws ShopxException
   */
  @Override
  public List<SysOrgModel> selectListByParOrgId(String parOrgId) throws ShopxException {
//    Object orgSubList = redisCacheService.get(CommonConstant.CacheKey.ORG_SUBLIST_CACHE+parOrgId);
//    if(orgSubList==null){
//      List allList = this.selectAllList();
//      List<SysOrgModel> subList = this.getSubOrgList(allList,parOrgId);
//      redisCacheService.set(CommonConstant.CacheKey.ORG_SUBLIST_CACHE+parOrgId,subList,3600);
//      return subList;
//    }else{
//      return  (List<SysOrgModel>)orgSubList;
//    }
    //暂时不走缓存
    List allList = this.selectAllList();
    List<SysOrgModel> subList = this.getSubOrgList(allList,parOrgId);
    return subList;
  }

  private List<SysOrgModel> getSubOrgList(List<SysOrgModel> orgList, String targetOrgId) {
    // 1. 预处理：构建父ID到子节点列表的映射（提升查询效率）
    Map<String, List<SysOrgModel>> parentMap = orgList.stream()
            .collect(Collectors.groupingBy(SysOrgModel::getParOrgId));

    // 2. 初始化结果列表和处理队列
    List<SysOrgModel> result = new ArrayList<>();
    Queue<LevelOrgDTO> queue = new LinkedList<>();

    // 3. 添加第一级子节点（直接子节点）
    int initialLevel = 1;
    parentMap.getOrDefault(targetOrgId, Collections.emptyList())
            .forEach(child -> queue.offer(new LevelOrgDTO(child, initialLevel)));

    // 4. 广度优先遍历（BFS）处理队列
    while (!queue.isEmpty()) {
      LevelOrgDTO levelOrg = queue.poll();
      SysOrgModel currentOrg = levelOrg.org;
      int currentLevel = levelOrg.level;

      // 加入结果列表
      result.add(currentOrg);
      // 控制层级深度（最多 4 级）
      if (currentLevel < 4) {
        // 获取下一级子节点
        List<SysOrgModel> children = parentMap.getOrDefault(currentOrg.getOrgId(), Collections.emptyList());
        int nextLevel = currentLevel + 1;
        children.forEach(child -> queue.offer(new LevelOrgDTO(child, nextLevel)));
      }
    }
    return result;
  }

  private List<SysOrgModel> selectAllList() throws ShopxException {
    Object orgList = redisCacheService.get(CommonConstant.CacheKey.ORG_LIST_CACHE);
    if(orgList==null){
      List<SysOrgModel> list = sysOrgDao.selectList(new SysOrgModel());
      redisCacheService.set(CommonConstant.CacheKey.ORG_LIST_CACHE,list);
      return list;
    }else{
      return  (List<SysOrgModel>)orgList;
    }
  }

  @Override
  public SysOrgModel selectByPrimaryKey(SysOrg sysOrg) throws ShopxException {
    if (sysOrg == null) {
      throw new ShopxException(ResultCodeEnum.PAR_NULL);
    }
    Object orgInfo = redisCacheService.get(CommonConstant.CacheKey.ORG_CACHE+sysOrg.getOrgId());
    if(orgInfo==null){
      sysOrg.setCpId(super.getUserCpId());
      SysOrgModel som = sysOrgDao.selectByPrimaryKey(sysOrg);
      redisCacheService.set(CommonConstant.CacheKey.ORG_CACHE+sysOrg.getOrgId(),orgInfo);
      return som;
    }else{
      return (SysOrgModel)orgInfo;
    }
  }

  @Override
  public int insertSelective(SysOrg sysOrg) throws ShopxException {
    if (sysOrg == null) {
      throw new ShopxException(ResultCodeEnum.PAR_NULL);
    }
    String id = sysSeqService.getTabSeq("SysOrg", 6, null);
    sysOrg.setOrgId(id);
    sysOrg.setCpId(super.getUserCpId());
    sysOrg.setDefaultFlag(CommonConstant.DefaultFlag.N);
    sysOrg.setOrgState(CommonConstant.State.EFFECTIVE);
    int result = sysOrgDao.insertSelective(sysOrg);
    if (result != 1) {
      throw new ShopxException(ResultCodeEnum.DB_ERROR);
    }
    redisCacheService.del(CommonConstant.CacheKey.ORG_LIST_CACHE);
    return result;
  }

  @Override
  public int updateByPrimaryKeySelective(SysOrg sysOrg) throws ShopxException {
    if (sysOrg == null) {
      throw new ShopxException(ResultCodeEnum.PAR_NULL);
    }
    SysOrgModel model = this.selectByPrimaryKey(sysOrg);
    if(CommonConstant.DefaultFlag.Y.equals(model.getDefaultFlag())){
      throw new OriginException("默认部门不允许编辑");
    }
    int result = sysOrgDao.updateByPrimaryKeySelective(sysOrg);
    if (result != 1) {
      throw new ShopxException(ResultCodeEnum.DB_ERROR);
    }
    redisCacheService.del(CommonConstant.CacheKey.ORG_CACHE+sysOrg.getOrgId());
    redisCacheService.del(CommonConstant.CacheKey.ORG_LIST_CACHE);
    return result;
  }

  @Override
  public int deleteByPrimaryKey(SysOrg sysOrg) throws ShopxException {
    if (sysOrg == null) {
      throw new ShopxException(ResultCodeEnum.PAR_NULL);
    }
    SysOrgModel model = this.selectByPrimaryKey(sysOrg);
    if(CommonConstant.DefaultFlag.Y.equals(model.getDefaultFlag())){
      throw new OriginException("默认部门不允许删除");
    }
    int result = sysOrgDao.deleteByPrimaryKey(sysOrg);
    if (result != 1) {
      throw new ShopxException(ResultCodeEnum.DB_ERROR);
    }
    redisCacheService.del(CommonConstant.CacheKey.ORG_CACHE+sysOrg.getOrgId());
    redisCacheService.del(CommonConstant.CacheKey.ORG_LIST_CACHE);
    return result;
  }

  private int selectCount(SysOrgModel sysOrg) throws ShopxException {
    return sysOrgDao.selectCount(sysOrg);
  }

  private List<SysOrgModel> selectList(SysOrgModel sysOrg) throws ShopxException {
    List<SysOrgModel> list = sysOrgDao.selectList(sysOrg);
    return list;
  }

  @Override
  public PageDTO<SysOrgModel> getListPage(SysOrgModel sysOrg) throws ShopxException {
    if (sysOrg == null) {
      throw new ShopxException(ResultCodeEnum.PAR_NULL);
    }
    PageDTO<SysOrgModel> pageDTO = new PageDTO<SysOrgModel>();
    sysOrg.setCpId(super.getUserCpId());
    //获取当前用户所在部门
    List<SysUserOrgModel> list = super.getUserOrgIList();
    if(list==null || list.size()==0){
      throw new OriginException("当前登录用户没有配置任何组织机构");
    }
    String orgIdChk[] = new String[list.size()];
    for(int i=0;i<list.size();i++){
      orgIdChk[i] = list.get(i).getOrgId();
    }
    sysOrg.setOrgIdChk(orgIdChk);
    pageDTO.setiTotalDisplayRecords(selectCount(sysOrg));
    pageDTO.setData(selectList(sysOrg));
    return pageDTO;
  }

  @Override
  public List<SysOrgModel> queryOrgNodeList() throws ShopxException {
    //查询登录用户的组织机构编号
    String orgId = super.getUserOrgId();
    SysOrgModel org = new SysOrgModel();
    org.setRootId(orgId);
    List<SysOrgModel> list = selectNodeList(org, true);
    if (list == null || list.size() == 0) {
      throw new OriginException("99999", "当前节点没有子节点菜单");
    }
    return list;
  }


  private List<SysOrgModel> selectNodeList(SysOrgModel org, boolean isExpand) throws ShopxException {
    SysOrgModel sysOrgModel = new SysOrgModel();
    sysOrgModel.setRootId(org.getRootId());
    List<SysOrgModel> list = sysOrgDao.selectOrgTreeList(sysOrgModel);
    if (list != null && list.size() > 0) {
      String[] orgIdChk = new String[list.size()];
      for (int i = 0; i < list.size(); i++) {
        orgIdChk[i] = list.get(i).getOrgId();
      }
      org.setOrgIdChk(orgIdChk);
    }
    org.setCpId(super.getUserCpId());
    List<SysOrgModel> list2 = sysOrgDao.selectListByOrgIds(org);
    if (list2.size() == 0) {
      return null;
    }
    List<SysOrgModel> modelList = new ArrayList<SysOrgModel>();
    for (SysOrg u : list2) {
      modelList.add((SysOrgModel) ClazzUtil.copy(u, new SysOrgModel()));
    }
    for (SysOrgModel orgModel : modelList) {
      orgModel.setId(orgModel.getOrgId());
      orgModel.setPid(orgModel.getParOrgId());
      orgModel.setText(orgModel.getOrgName());
      orgModel.setHasChildren(true);
      orgModel.setExpanded(isExpand);
    }
    return modelList;
  }

  @Override
  public List<SysOrgModel> selectOrgTreeList(SysOrgModel sysOrg) {
    String userId = super.getLoginUserId();
    SysUserModel sysUser = new SysUserModel();
    sysUser.setUserId(userId);
    sysUser.setCpId(super.getUserCpId());
    SysUserModel sysUserModel = sysUserDao.selectByPrimaryKey(sysUser);
    if(sysUserModel==null){
      throw new OriginException("99999","用户不存在");
    }
    //查询部门是否是管理员权限
//    SysOrg sysOrgParam = new SysOrg();
//    sysOrgParam.setOrgId(super.getUserOrgId());
//    sysOrgParam.setCpId(super.getUserCpId());
//    SysOrgModel som = sysOrgDao.selectByPrimaryKey(sysOrgParam);
//    if(som==null){
//      throw new OriginException("99999","用户所属部门不存在");
//    }
    //查询根节点
    SysOrgModel param = new SysOrgModel();
    param.setCpId(super.getUserCpId());
    param.setOrgLevel(1);
    List<SysOrgModel> orgList = sysOrgDao.selectList(param);
    if(orgList==null || orgList.size()==0){
      throw new OriginException("99999","尚未录入部门");
    }
//    if(CommonConstant.OrgAdminFlag.Y.equals(som.getAdminFlag())){
//      sysOrg.setRootId(orgList.get(0).getOrgId());
//    }else{
//      sysOrg.setRootId(sysUserModel.getOrgId());
//    }
    List<SysOrgModel> list = sysOrgDao.selectOrgTreeList(sysOrg);
    for (SysOrgModel model : list) {
      String prefix = "";
      if (model.getOrgLevel() > 1) {
        for(int i=1;i<=model.getOrgLevel();i++){
          prefix += "-";
        }
        model.setOrgName(prefix + model.getOrgName());
      }
    }
    return list;
  }


  @Override
  public String queryOrgTreeList(String parOrgId) throws ShopxException {
    SysOrgModel org = new SysOrgModel();
    if (parOrgId != null) {
      org.setParOrgId(parOrgId);
    }
    org.setOrgLevel(null);
    List<SysOrgModel> list = this.selectList(org);
    return integrationTreeOrg(list,"").toJSONString();
  }

  @Override
  public String queryEditOrgNodeList(SysOrgModel sysOrg){
    SysOrgModel org = new SysOrgModel();
    if (sysOrg.getParOrgId() != null) {
      org.setParOrgId(sysOrg.getParOrgId());
    }
    org.setOrgLevel(null);
    List<SysOrgModel> list = this.selectList(org);
    return integrationTreeOrg(list,sysOrg.getIds()).toJSONString();
  }


  /**
   * @param list
   * @description:整合菜单
   * @author:lituo
   * @date:2021-01-05 11:06 AM
   * @return:net.sf.json.JSONArray
   */
  private JSONArray integrationTreeOrg(List<SysOrgModel> list, String ids) throws ShopxException {
    String userOrgsId[] = super.getUserOrgId().split(",");
    List<SysOrgModel> firstList = new ArrayList<SysOrgModel>();
    List<SysOrgModel> secondList = new ArrayList<SysOrgModel>();
    List<SysOrgModel> thirdList = new ArrayList<SysOrgModel>();
    List<SysOrgModel> fourList = new ArrayList<SysOrgModel>();
    JSONArray jsonArr = new JSONArray();
    for (SysOrgModel orgModal : list) {
      if (orgModal.getOrgLevel() == 1) {
        firstList.add(orgModal);
      }
      if (orgModal.getOrgLevel() == 2) {
        secondList.add(orgModal);
      }
      if (orgModal.getOrgLevel() == 3) {
        thirdList.add(orgModal);
      }
      if (orgModal.getOrgLevel() == 4) {
        fourList.add(orgModal);
      }
    }
    for (SysOrgModel fOrgModal : firstList) {
      // 第一层
      Map<String, Object> map = new HashMap<String, Object>();
      map.put("id", fOrgModal.getOrgId());
      if(!StringUtil.isEmpty(ids) && this.containsId(ids,fOrgModal.getOrgId())){
        boolean existsFlag = list.stream()
                .anyMatch(model -> model.getParOrgId() != null && model.getParOrgId().equals(fOrgModal.getOrgId()));
        if(!existsFlag){
          //没有下级，且勾选了，则标记为勾选
          map.put("checked", true);
        }
//        map.put("checked", true);
      }
      map.put("title", fOrgModal.getOrgName());
      map.put("icon", "layui-icon layui-icon-file");
      map.put("level", fOrgModal.getOrgLevel());
      if(Arrays.asList(userOrgsId).contains(fOrgModal.getOrgId())){
        map.put("disabled", false);
      }else{
        map.put("disabled", true);
      }
      //循环第一层，标记二级菜单
      List<Map<String, Object>> twoList = new ArrayList<Map<String, Object>>();
      for(SysOrgModel sOrgModal:secondList){
        if(sOrgModal.getParOrgId().equals(fOrgModal.getOrgId())){
          Map<String, Object> map2 = new HashMap<String, Object>();
          map2.put("id", sOrgModal.getOrgId());
          if(!StringUtil.isEmpty(ids) && this.containsId(ids,sOrgModal.getOrgId())){
//            map2.put("checked", true);
            boolean existsFlag = list.stream()
                    .anyMatch(model -> model.getParOrgId() != null && model.getParOrgId().equals(sOrgModal.getOrgId()));
            if(!existsFlag){
              //没有下级，且勾选了，则标记为勾选
              map2.put("checked", true);
            }
          }
          map2.put("title", sOrgModal.getOrgName());
          map2.put("icon", "layui-icon layui-icon-file");
          map2.put("level", sOrgModal.getOrgLevel());
          if(Arrays.asList(userOrgsId).contains(sOrgModal.getOrgId())){
            map2.put("disabled", false);
          }else{
            map2.put("disabled", true);
          }
          List<Map<String, Object>> thList = new ArrayList<Map<String, Object>>();
          for(SysOrgModel tOrgModal:thirdList){
            if(tOrgModal.getParOrgId().equals(sOrgModal.getOrgId())){
              Map<String, Object> map3 = new HashMap<String, Object>();
              map3.put("id", tOrgModal.getOrgId());
              if(!StringUtil.isEmpty(ids) && this.containsId(ids,tOrgModal.getOrgId())){
                //验证是否有下级菜单，有则不勾选，否则勾选
                boolean existsFlag = list.stream()
                        .anyMatch(model -> model.getParOrgId() != null && model.getParOrgId().equals(tOrgModal.getOrgId()));
                if(!existsFlag){
                  //没有下级，且勾选了，则标记为勾选
                  map3.put("checked", true);
                }
//                map3.put("checked", true);
              }
              map3.put("title", tOrgModal.getOrgName());
              map3.put("icon", "layui-icon layui-icon-file");
              map3.put("level", tOrgModal.getOrgLevel());
              if(Arrays.asList(userOrgsId).contains(tOrgModal.getOrgId())){
                map3.put("disabled", false);
              }else{
                map3.put("disabled", true);
              }
              List<Map<String, Object>> foList = new ArrayList<Map<String, Object>>();
              for(SysOrgModel fourOrgModal:fourList){
                if(fourOrgModal.getParOrgId().equals(tOrgModal.getOrgId())){
                  Map<String, Object> map4 = new HashMap<String, Object>();
                  map4.put("id", fourOrgModal.getOrgId());
                  if(!StringUtil.isEmpty(ids) && this.containsId(ids,fourOrgModal.getOrgId())){
                    map4.put("checked", true);
                  }
                  map4.put("title", fourOrgModal.getOrgName());
                  map4.put("icon", "layui-icon layui-icon-file");
                  map4.put("level", fourOrgModal.getOrgLevel());
                  if(Arrays.asList(userOrgsId).contains(fourOrgModal.getOrgId())){
                    map4.put("disabled", false);
                  }else{
                    map4.put("disabled", true);
                  }
                  foList.add(map4);
                }
              }
              if(foList!=null && foList.size()>0){
                map3.put("children",foList);
              }
              thList.add(map3);
            }
          }
          if(thList!=null && thList.size()>0){
            map2.put("children",thList);
          }
          twoList.add(map2);
        }
      }
      if(twoList!=null && twoList.size()>0){
        map.put("children",twoList);
      }
      jsonArr.add(map);
    }
    return jsonArr;
  }

  /**
   * 验证是否存在记录
   * @param ids
   * @param a
   * @return
   */
  private boolean containsId(String ids, String a) {
    return Arrays.stream(ids.split(","))
            .map(String::trim) //Added to handle potential spaces around numbers.
            .anyMatch(id -> id.equals(a));
  }

//  @Override
//  public boolean adminFlagCheck(String orgId){
//    SysOrg sysOrg = new SysOrg();
//    sysOrg.setOrgId(orgId);
//    SysOrgModel som = sysOrgDao.selectByPrimaryKey(sysOrg);
//    if(sysOrg==null){
//      return false;
//    }
//    if(CommonConstant.OrgAdminFlag.Y.equals(som.getAdminFlag())){
//      return true;
//    }else{
//      return false;
//    }
//  }
}

